#include "PrecompiledHeader.h"
#include "Thread.h"

/*--------------------------------------------------------------------------*/

Thread::Thread()
{
	this->m_sdlThread = NULL;

	this->m_isBusy = false;
	this->m_taskDoneSoFar = 0;
}

/*--------------------------------------------------------------------------*/

Thread::~Thread()
{
	if (this->m_sdlThread != NULL)
	{
		SDL_KillThread(this->m_sdlThread);
	}
}

/*--------------------------------------------------------------------------*/

bool Thread::GetIsBusy() const
{
	return this->m_isBusy;
}

/*--------------------------------------------------------------------------*/

void Thread::SetIsBusy(bool nbusy)
{
	this->m_isBusy = nbusy;
}

/*--------------------------------------------------------------------------*/

void Thread::IncrementTaskDoneSoFar()
{
	++this->m_taskDoneSoFar;
}

/*--------------------------------------------------------------------------*/

void Thread::SetTaskDoneSoFar(uint i)
{
	this->m_taskDoneSoFar = i;
}

/*--------------------------------------------------------------------------*/

uint Thread::GetTaskDoneSoFar()
{
	return this->m_taskDoneSoFar;
}

/*--------------------------------------------------------------------------*/

void Thread::Wait()
{
	this->Stop();

	SDL_WaitThread(this->m_sdlThread, NULL);
	this->m_sdlThread = NULL;
}

/*--------------------------------------------------------------------------*/

void Thread::Start()
{
	this->m_sdlThread = SDL_CreateThread(SingleThread, (void*) this);
	AssertLogC(!this->m_sdlThread, "Failed to create new thread: %s", SDL_GetError());
}

/*--------------------------------------------------------------------------*/

bool Thread::IsLooping()
{
	return this->m_keepThreadAlive;
}

/*--------------------------------------------------------------------------*/

void Thread::Stop()
{
	this->m_keepThreadAlive = false;
}

/*--------------------------------------------------------------------------*/

int SingleThread(void* data)
{
	Thread* that = (Thread*) data;
	CalcArg action;

	while (that->IsLooping())
	{
		that->SetIsBusy(true);
		g_Calc->GetNextTask(1, action);

		if (action.m_calc != NULL)
		{
			action.m_calc->DoCalc(action.m_arg);
			that->IncrementTaskDoneSoFar();

			while (1)
			{
				g_Calc->GetNextTask(1, action);

				if (action.m_calc)
				{
					action.m_calc->DoCalc(action.m_arg);
					that->IncrementTaskDoneSoFar();
				}
				else
				{
					break;
				}
			}

			that->SetIsBusy(false);
		}
		else
		{
			that->SetIsBusy(false);
			g_Sdl->Delay(1);
		}
	}

	return 0;
}

/*--------------------------------------------------------------------------*/
